package WIAB::Controller::User;

use strict;
use warnings;
use base 'Catalyst::Controller';

use Authen::Htpasswd; # set, store and delete from auth store functions.



=head2 ACTION

index: Private

Checks for logged in user, if not, forwards to admin page, otherwise
to home page.

=cut

sub auto : Private {
    my ($self, $c) = @_;
    $c->stash->{template} = 'login.tt';
    if(!$c->login()) {
        $c->stash->{message} = 'Please login.';
    }
    else {
        if ($c->req->param('public') ) {
            $c->session_expire_key( __user => 600 );
        }
        $c->res->redirect($c->uri_for('/content', { login => 1} ));
    }
}

=head2 ACTION

login : Local

Forwards to index for user checking and login page if nescessary

=cut

sub login : Local {
    my ($self, $c) = @_;
    $c->detach('auto');
}

=head2 ACTION

logout : Local

Logs user out

=cut

sub logout : Local {
    my ($self, $c) = @_;

    $c->logout;
    $c->res->redirect($c->uri_for('/'));
}

=head2 ACTION

admin : Local

Checks for user and sends to user admin page if logged in, else sends
to login screen.

=cut

sub admin : Local {
    my ($self, $c) = @_;
    if(!$c->user) {
        $c->detach('auto');
    }
    else {
        $c->stash->{template} = 'user_admin.tt';
        my $auth = _get_auth($c);
        my @users;
        map {push @users, $_->username} $auth->all_users;
        # $c->stash->{del} = 1 if scalar(@users) > 1;
        $c->stash->{users} = \@users;        
    }
}

=head2 ACTION

change_pass : Local

Worker to change the user's password.

=cut

sub change_pass : Local {
    my ($self, $c) = @_;
    my $auth = _get_auth($c);
    my $uid = $c->req->param('user');
    my $old_pw = $c->req->param('old_password');
    my $new_pw = $c->req->param('password');
    my $new_pw_conf = $c->req->param('password_confirm');
    if ($auth->check_user_password($uid,$old_pw)) {
        if ($new_pw eq $new_pw_conf) {
            # ok, change it
            my $user = $auth->lookup_user($uid);
            $auth->update_user($uid, $new_pw);
            $DB::single=1;
            $c->flash->{message} = 'Password successfully changed!';
            $c->res->redirect($c->uri_for('/user/admin'));
            return;
        }
        else {
            $c->flash->{err} = "New passwords do not match, please try again";
            $c->res->redirect($c->uri_for('/user/admin'));
            return;
        }
    }
    else {
        $c->flash->{err} = "Old password was incorrect, please try again";
        $c->res->redirect($c->uri_for('/user/admin'));
        return;
    }
}

=head2 ACTION

add : Local

Worker to add a new user

=cut


sub add : Local {
    my ($self, $c) = @_;
    my $auth = _get_auth($c);
    my $new_uid = $c->req->param('user');
    my $my_pw = $c->req->param('password');
    my $nu_pw = $c->req->param('nu_password');
    my $nu_pw_conf = $c->req->param('nu_password_confirm');
    if ($auth->check_user_password($c->user, $my_pw)) {
        if (! $auth->lookup_user($new_uid)) {
            if ($nu_pw ne $nu_pw_conf) {
                $c->flash->{err_add} = "New user passwords do not match, please try again";
            }
            else {
                $c->flash->{err_add} = "New user $new_uid added";
                $auth->add_user($new_uid, $nu_pw);
                $c->res->redirect($c->uri_for('/user/admin'));
                return;
            }
        }
        else {
            $c->flash->{err_add} = "User $new_uid already exists.  Please try again";
            $c->res->redirect($c->uri_for('/user/admin'));
            return;
            
        }
    }
    
    else {
        $c->flash->{err_add} = "Your password was incorrect, please try again";
        $c->res->redirect($c->uri_for('/user/admin'));
        return;
    }
}

=head2 ACTION

del : Local

Worker to delete a user.

=cut


sub del : Local {
    my ($self, $c) = @_;
    my $auth = _get_auth($c);
    if (scalar($auth->all_users) == 1) {
        $c->detach('_one_user');
    }
    elsif ( $c->req->param('user') eq $c->user ) {
        $c->flash->{err_del} = "You can't delete yourself";
        $c->res->redirect($c->uri_for('/user/admin'));
        return;
    }
    elsif (!$auth->
                check_user_password($c->user, $c->req->param('password'))
            ) {
        $DB::single=1;
        $c->flash->{err_del} = "Your password was incorrect, please try again";
        $c->res->redirect($c->uri_for('/user/admin'));
        return;
    }
    elsif (!$auth->lookup_user($c->req->param('user'))) {
        $c->flash->{err_del} = "User " . $c->req->param('user') . " does not exist";
        $c->res->redirect($c->uri_for('/user/admin'));
        return;
    }
    else {
        $c->forward('del_confirm');
    }
}

sub del_confirm : Local  {
    my ($self, $c ) = @_;
    my $auth = _get_auth($c);
    if (scalar($auth->all_users) == 1) {
        $c->detach('_one_user');
    }
    else {
        $c->stash->{template} = 'confirm_user_del.tt';
    }
}

=head2 ACTION

do_user_del : Local

does the dirty work of deleting the user

=cut

sub do_user_del : Local {
    my ($self, $c) = @_;
    my $user2del = $c->req->param('user');
    my $auth = _get_auth($c);
    $auth->delete_user($user2del);
    $c->flash->{message} = "User $user2del deleted successfully";
    $c->res->redirect($c->uri_for('/user/admin'));
    return;
}


=head2 ACTION

_one_user

sets flash and redirects to admin page if only one user

=cut

sub _one_user : Private {
    my ($self, $c) = @_;
    $c->flash->{message} = "Tried to delete the last user.  I can't let you do that";
    $c->res->redirect($c->uri_for('/user/admin'));
    return;
}

=head2 SUB

_get_auth()

returns the auth store

=cut

sub _get_auth {
    my $c = shift;
    return Authen::Htpasswd->new($c->config->{authentication}->{htpasswd}, { encrypt_hash => 'md5' });
}

=head1 NAME

WIAB::Controller::User - Catalyst Controller


=head1 SYNOPSIS

/login, /user (forward from L<WIAB::Controller::Root> and /user/login
lead to a login screen. /user/logout which logs you out.  Loggging in
is compulsory for edit pages.

=head1 AUTHOR

Kieren Diment

=head1 LICENSE

This library is free software, you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut


1;
